#include "../../Headers/DataAccessors/reservationdataaccessor.h"

#include "../../Headers/DataAccessors/roomdataaccessor.h"
#include "../../Headers/DataAccessors/clientdataaccessor.h"
#include "../../Headers/DataAccessors/advancedoptiondataaccessor.h"

#include <QSqlError>

ReservationDataAccessor::ReservationDataAccessor(QString databaseName):
    DB(databaseName)
{
}

QSqlQueryModel * ReservationDataAccessor::getReservations()
{
    QSqlQueryModel * model = new QSqlQueryModel();
    model->setQuery("select reservation.id, client.lastName, room.number, reservation.arrival_date, reservation.departure_date from reservation, client, room"
                    " where reservation.id_client=client.id and reservation.id_room=room.id", db);
    return model;
}

bool ReservationDataAccessor::setReservation(Reservation reservation)
{
    QSqlQuery query(db);
    query.prepare("insert into reservation (id_client, id_room, arrival_date, departure_date, is_buy)"
                  "values(:id_client, :id_room, :arrival_date, :departure_date, :is_buy)");
    query.bindValue(":id_client", reservation.getClient().getId());
    query.bindValue(":id_room", reservation.getRoom().getId());
    query.bindValue(":arrival_date", reservation.getArrivalDate().toString("dd.MM.yyyy"));
    query.bindValue(":departure_date", reservation.getDepartureDate().toString("dd.MM.yyyy"));
    query.bindValue(":is_buy", reservation.getIsBuy());
    if (query.exec())
    {
        //определяем id добавленной записи брони
        QSqlQueryModel *model = getReservations();
        int id = model->data(model->index(model->rowCount() - 1, 0)).toInt();
        QList<AdvancedOption*> options = reservation.getOptions();
        for(int i = 0; i < options.count(); i++)
        {
            QSqlQuery queryOptions(db);
            queryOptions.prepare("insert into str_of_option (id_reservation, id_option)"
                                 "values(:id_reservation, :id_option)");
            queryOptions.bindValue(":id_reservation", id);
            queryOptions.bindValue(":id_option", options[i]->getId());
            if (queryOptions.exec())
            {
                qDebug("and options ok");
            }
            else
            {
                qDebug("options are bad");
                qDebug(queryOptions.lastError().text().toAscii());
            }
        }

        qDebug("yes");
        return true;
    }
    else
    {
        qDebug(query.lastError().text().toAscii());
        return false;
    }
}

Reservation * ReservationDataAccessor::getReservation(int id)
{
    QSqlQuery query(db);
    if (query.exec("select id, id_client, id_room, arrival_date, departure_date, is_buy from reservation where id = " + QString::number(id)))
    {
        while(query.next())
        {
            ClientDataAccessor dataClient;
            int client_id = query.value(1).toInt();
            Client *client = dataClient.getClient(client_id);

            RoomDataAccessor dataRoom;
            int room_id = query.value(2).toInt();
            Room *room = dataRoom.getRoom(room_id);

            Reservation *reservation = new Reservation(
                        query.value(0).toInt(),//id
                        *client,
                        *room,
                        QDate::fromString(query.value(3).toString(), "dd.MM.yyyy"),
                        QDate::fromString(query.value(4).toString(), "dd.MM.yyyy"),
                        query.value(4).toBool()
                        );

            //получаем опции
            QSqlQuery queryOptions(db);
            QList<AdvancedOption*> options;
            if (queryOptions.exec("select id, id_reservation, id_option from str_of_option"
                                  " where id_reservation=" + QString::number(id)))
            {
                while(queryOptions.next())
                {
                    AdvancedOptionDataAccessor optionData;
                    int option_id = queryOptions.value(2).toInt();
                    AdvancedOption *option = optionData.getAdvancedOption(option_id);
                    options.push_back(option);
                }
            }

            reservation->setOptions(options);

            return reservation;
        }
    }

    return NULL;
}

bool ReservationDataAccessor::deleteReservation(Reservation reservation)
{
    //удаляем дополнительные опции
    QSqlQuery query(db);
    if (query.exec("delete from str_of_option where id_reservation=" + QString::number(reservation.getId())))
    {
        QSqlQuery queryReserv(db);
        if (queryReserv.exec("delete from reservation where id=" + QString::number(reservation.getId())))
            return true;
        else
            qDebug(queryReserv.lastError().text().toAscii());
    }
    else
        qDebug(query.lastError().text().toAscii());
    return false;
}

bool ReservationDataAccessor::editReservation(Reservation reservation)
{
    //удаляем дополнительные опции
    QSqlQuery queryOptions(db);
    if (queryOptions.exec("delete from str_of_option where id_reservation=" + QString::number(reservation.getId())))
    {
        QSqlQuery query(db);
        query.prepare("update reservation set id_client=:id_client, id_room=:id_room,"
                      "arrival_date=:arrival_date, departure_date=:departure_date, is_buy=:is_buy where id=:id");
        query.bindValue(":id", reservation.getId());
        query.bindValue(":id_client", reservation.getClient().getId());
        query.bindValue(":id_room", reservation.getRoom().getId());
        query.bindValue(":arrival_date", reservation.getArrivalDate().toString("dd.MM.yyyy"));
        query.bindValue(":departure_date", reservation.getDepartureDate().toString("dd.MM.yyyy"));
        query.bindValue(":is_buy", reservation.getIsBuy());

        if (query.exec())
        {
            //добавляем опции
            //определяем id добавленной записи брони
            int id = reservation.getId();
            QList<AdvancedOption*> options = reservation.getOptions();
            qDebug("options" + QString::number(options.count()).toAscii());
            for(int i = 0; i < options.count(); i++)
            {
                QSqlQuery queryAddOptions(db);
                queryAddOptions.prepare("insert into str_of_option (id_reservation, id_option)"
                                     "values(:id_reservation, :id_option)");
                queryAddOptions.bindValue(":id_reservation", id);
                queryAddOptions.bindValue(":id_option", options[i]->getId());
                if (queryAddOptions.exec())
                {
                    qDebug("and options ok");
                }
                else
                {
                    qDebug("options are bad");
                    qDebug(queryAddOptions.lastError().text().toAscii());
                }
            }
            return true;
        }
        else
            qDebug(query.lastError().text().toAscii());
    }
    else
        qDebug(queryOptions.lastError().text().toAscii());

    return false;
}

QSqlQueryModel * ReservationDataAccessor::getReservationsWithFilter(QString searchString)
{
    QSqlQueryModel *model = new QSqlQueryModel();
    model->setQuery("select reservation.id, client.firstName, client.lastName, room.number, reservation.arrival_date, reservation.departure_date from reservation, client, room"
                    " where reservation.id_client=client.id and reservation.id_room=room.id and  (client.lastName like '" + searchString +  "%' or client.firstName like '" + searchString +  "%' or room.number like '" + searchString +  "%')", db);

    //qDebug(model->query().lastError().text().toAscii());
    return model;
}
